﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using Microsoft.Reporting.WinForms;
using Tracker.Services;
using Tracker.Data.DataTransfer;
using Tracker.Views;
using Tracker.Helper;


namespace Tracker.Presenters
{
    public class TrackerPresenter :ITrackerPresenter
    {
        #region private fields
        
        private List<string> _filterTime = new List<string> { "All", "Last Day", "Last 2 Days", "Last Week", "Last 2 Weeks", "Last Month", "Last 2 Months" };
        private string _rootPath = new AppSetting().GetAppsetting("FileRootPath");

        private ITaskData _td;
        private ITrackerView _tv;
        
        #endregion
        

        public TrackerPresenter(ITaskData td,ITrackerView tv)
        {
            _td = td;
            _tv = tv;
            

            //search fileds initialize
            _tv.DetailCreateTimeStart = DateTime.Now.AddMonths(-2);
            _tv.DetailCreateTimeEnd = DateTime.Now;
            _tv.DetailUpdateTimeStart = DateTime.Now.AddMonths(-2);
            _tv.DetailUpdateTimeEnd = DateTime.Now;

            _tv.SummaryCreateTimeStart = DateTime.Now.AddMonths(-2);
            _tv.SummaryCreateTimeEnd = DateTime.Now;
            _tv.SummaryUpdateTimeStart = DateTime.Now.AddMonths(-2);
            _tv.SummaryUpdateTimeEnd = DateTime.Now;

            _tv.SummaryReportCreateTimeStart = DateTime.Now.AddMonths(-2);
            _tv.SummaryReportCreateTimeEnd = DateTime.Now;
            _tv.SummaryReportUpdateTimeStart = DateTime.Now.AddMonths(-2);
            _tv.SummaryReportUpdateTimeEnd = DateTime.Now;

            InitializeTaskViewFilter();


            _tv.ShowOptionForm += ShowOption;
            _tv.InitializeLogView += InitializeLogView;
            _tv.InitializeReport += InitializeReport;
            _tv.UpdateLog += UpdateLog;
            _tv.DeleteLog += DeleteLog;
            _tv.DeleteTask += DeleteTask;
            _tv.UpdateTask += UpdateTask;
            _tv.InitializeTaskView += InitializeTaskView;
            _tv.InitializeSummarySearchView += InitializeSummarySearchView;
            _tv.InitializeDetailSearchView += InitializeDetailSearchView;
            _tv.FilesLinkClicked += Files_LinkClicked;

            //InitializeTaskView();
        }

        public ITrackerView TrackerView 
        {
            get { return _tv; }
        }
        #region events handling

        public void ShowOption(object sender, EventArgs e)
        {
            (CastleWindsor.Resolve<OptionPresenter>().OptionView as Form).Show();
        }
        public void Files_LinkClicked(object sender,string e)
        {
         string path = _rootPath + @"\" + e;

                if (Directory.Exists(path))
                {
                    Process.Start("explorer.exe", path);

                }
                else if (_tv.FilePath == "Create Folder")
                {
                    if (Directory.Exists(_rootPath) || true)
                    {

                        Directory.CreateDirectory(_rootPath + @"\" + e);
                        _tv.FilePath = _rootPath + @"\" + e;
                    }
                }
        }

        public void InitializeLogView(object sender, Task e)
        {
            InitializeLogView(e);
        }

        public void InitializeReport(object sender, EventArgs e)
        {
            InitializeReport();
        }
        public void InitializeTaskView(object sender, EventArgs e)
        {
            InitializeTaskView();
        }
        public void InitializeSummarySearchView(object sender, EventArgs e)
        {
            InitializeSummarySearchView();
        }
        public void InitializeDetailSearchView(object sender, EventArgs e)
        {
            InitializeDetailSearchView();
        }

        public void UpdateLog(object sender, Log e)
        {
            if (e!=null)
            {
                var l = UpdateLog(e);
                e.ID = l.ID;
                e.ModifiedDate = l.ModifiedDate;
            }
        }

        public void DeleteLog(object sender, Log e)
        {
            DeleteLog(e);
        }

        public void DeleteTask(object sender, Task e)
        {
            DeleteTask(e);
        }

        public void UpdateTask(object sender, Task e)
        {
           var t = UpdateTask(e);
           e.ID = t.ID;
           e.CreatedDate = t.CreatedDate;
        }

        

        #endregion

        #region Detail Search/summary search/report Tab

        public void InitializeDetailSearchView()
        {
            var ll = _td.GetLogInfoList(_tv.DetailCreateTimeStart,
                                           _tv.DetailCreateTimeEnd,
                                           _tv.DetailUpdateTimeStart,
                                           _tv.DetailUpdateTimeEnd,
                                           _tv.DetailSearchWord);


            _tv.DetailsearchView = ll.Select(l1 => 
                new
                {
                    l1.TaskId,
                    Task = l1.Task_logTask == null ? string.Empty : l1.Task_logTask.Description,
                    LogId = l1.ID,
                    Log = l1.Description,
                    Status = l1.Status_logStatusDomain == null ? string.Empty : l1.Status_logStatusDomain.Status,
                    l1.Hours,
                    Date = l1.ModifiedDate
                })
                .OrderByDescending(l => l.TaskId)
                .ThenByDescending(l => l.LogId).ToList<dynamic>();
        }


        public void InitializeSummarySearchView()
        {
            var lt = _td.GetTaskInfoList(_tv.SummaryCreateTimeStart,
                                          _tv.SummaryCreateTimeEnd,
                                          _tv.SummaryUpdateTimeStart,
                                          _tv.SummaryUpdateTimeEnd);
            _tv.TaskSearchView = lt
                .Select(t =>
                {
                    var hours = t.Task_logLogList.Count < 1 ? 0 : t.Task_logLogList.Sum(l => l.Hours);
                    var date = t.Task_logLogList.Count < 1 ? DateTime.Now.AddYears(-100).ToShortDateString()
                                     : t.Task_logLogList.Max(l => l.ModifiedDate).Value.ToShortDateString();
                    return new
                    {
                        t.ID,
                        t.Description,
                        t.Status_taskStatusDomain.Status,
                        hours = hours,
                        StartDate = t.CreatedDate,
                        EndDate = date
                    };
                })
                                 .OrderBy(t => t.ID)
                                 .ToList<dynamic>();
        }

        public void InitializeReport()
        {
            var lt = _td.GetTaskInfoList(_tv.SummaryReportCreateTimeStart,
                                           _tv.SummaryReportCreateTimeEnd,
                                           _tv.SummaryReportUpdateTimeStart,
                                           _tv.SummaryReportUpdateTimeEnd)
                          .Select(t =>
                          {
                              var hours = t.Task_logLogList.Count < 1 ? 0 : t.Task_logLogList.Sum(l => l.Hours);
                              var date = t.Task_logLogList.Count < 1 ? DateTime.Now.AddYears(-100)
                                               : t.Task_logLogList.Max(l => l.ModifiedDate).Value;
                              return new ReportDataSummary()
                              {
                                  ID = t.ID,
                                  Description = t.Description,
                                  Status = t.Status_taskStatusDomain.Status,
                                  Hours = hours.Value,
                                  StartDate = t.CreatedDate.Value,
                                  EndDate = date
                              };
                          })
                                    .OrderBy(t => t.ID)
                                    .ToList();
            _tv.ReportPath = Directory.GetCurrentDirectory() + @"\ReportSummary.rdlc";
            _tv.ReportSource = lt;
        }

        #endregion

        #region Task input Tab

        public void InitializeTaskView()
        {
            var statusid = _tv.FilterStatus;
            DateTime datelimit = GetDatelimit( _tv.FilterTime);
            var la = _td.GetTasks(datelimit, statusid,_tv.InputSearchWord);

            //add customized properties
            var fields = _td.GetTaskField();
            var custTask = new BindingList<dynamic>(la.Select(
                t =>
                {
                    Dictionary<string, object> dict = new Dictionary<string, object>();

                    foreach (var item in fields)
                    {
                        dict.Add(item.AttributeName, "");
                    }
                    var tt = t.Add<dynamic>(dict);

                    foreach (var itemf in _td.GetTaskField(t.ID))
                    {
                        tt.Set<dynamic>(itemf.ObjectAttribute.AttributeName, itemf.Value);
                    }

                    return tt;
                }
                ).OrderBy(t => t.ID).ToList());
            custTask.AddingNew += new AddingNewEventHandler(AddNewTask);
            _tv.TaskInputView = custTask;
        }

        public void InitializeLogView(Task t)
        {
            if (t ==null)
            {
                _tv.LogInputView = null;
            }
            else
            {
                var dd = new BindingList<Log>(_td.GetLog(t.ID)
                                 .OrderBy(ddd => ddd.ID).ToList<Log>());
                if (dd.Count < 1)
                {
                    return;
                }
                
                dd.AddingNew += new AddingNewEventHandler(AddNewLog);

                _tv.LogInputView = dd;

                //set file folder path
                string path = t == null ? "not existing" : t.Description;
                if (Directory.Exists(_rootPath + @"\" + path))
                {
                    _tv.FilePath = _rootPath + @"\" + path;

                }
                else
                {
                    _tv.FilePath = "Create Folder";

                }
               
            }
            
        }

        private void AddNewLog(object sender, AddingNewEventArgs e)
        {
            var task = _tv.CurrentTask;
            if (task !=null)
            {
                e.NewObject = new Log()
                {
                    TaskId = task.ID,
                    StatusId = task.StatusId,
                    Hours = 0
                };

            }
            else
            {
                e.NewObject = null;
               _tv.ShowMessage("Please select task before creating logs");
            }
        }

        public void AddNewTask(object sender, AddingNewEventArgs e)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>();

            foreach (var item in _td.GetTaskField())
            {
                dict.Add(item.AttributeName, "");
            }
            e.NewObject = new Task() { StatusId = 1 }.Add<dynamic>(dict);
        }


        public void InitializeTaskViewFilter()
        {
            _tv.FilterTimeSource = _filterTime;
            _tv.FilterTime = "Last 2 Months";


            // status filter
            List<StatusDomain> retrieveStatusDomain = _td.GetStatusDomainList();
            retrieveStatusDomain.Add(new StatusDomain() { ID = 0, Status = "All" });
            _tv.FilterStatusSource = retrieveStatusDomain.OrderBy(s => s.ID).ToList();

        }

        public DateTime GetDatelimit(string date)
        {
            DateTime dateTime;
            switch (date)
            {
                case "All":
                    dateTime = DateTime.Now.AddYears(-10);
                    break;
                case "Last Week":
                    dateTime = DateTime.Now.AddDays(-7);
                    break;
                case "Last 2 Weeks":
                    dateTime = DateTime.Now.AddDays(-14);
                    break;
                case "Last Day":
                    dateTime = DateTime.Now.AddDays(-1);
                    break;
                case "Last 2 Days":
                    dateTime = DateTime.Now.AddDays(-2);
                    break;
                case "Last Month":
                    dateTime = DateTime.Now.AddMonths(-1);
                    break;
                case "Last 2 Months":
                    dateTime = DateTime.Now.AddMonths(-2);
                    break;


                default:
                    dateTime = DateTime.Now.AddDays(-1);
                    break;

            }
            return dateTime;
        }

        public Task UpdateTask(Task t)
        {
           return _td.UpdateTask(t);
        }

        public Log UpdateLog(Log l)
        {
           return _td.UpdateLog(l);
        }

        public void DeleteTask(Task t)
        {
            foreach (Log item in _td.GetLog(t.ID))
            {
                _td.DeleteLog(item.ID);
            }

            _td.DeleteTask(t.ID);
            InitializeTaskView();
            //remove log view
            InitializeLogView(new Task() { ID=0});
        }

        public void DeleteLog(Log l)
        {
            _td.DeleteLog(l.ID);
        }


        #endregion
        
    }
}
